home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / demos / VisualAge for Java 2.0 Entry / setup / data1.cab / ide-e / IDE / cache / L3CJCM (.txt) < prev    next >
Encoding:
Java Class File  |  1998-09-16  |  26.2 KB  |  1,321 lines

  1. package com.sun.java.swing.plaf.basic;
  2.  
  3. import com.sun.java.swing.event.TreeModelEvent;
  4. import com.sun.java.swing.event.TreeModelListener;
  5. import com.sun.java.swing.event.TreeSelectionEvent;
  6. import com.sun.java.swing.event.TreeSelectionListener;
  7. import com.sun.java.swing.plaf.TreeUI;
  8. import com.sun.java.swing.tree.DefaultMutableTreeNode;
  9. import com.sun.java.swing.tree.RowMapper;
  10. import com.sun.java.swing.tree.TreeModel;
  11. import com.sun.java.swing.tree.TreeNode;
  12. import com.sun.java.swing.tree.TreePath;
  13. import com.sun.java.swing.tree.TreeSelectionModel;
  14. import java.awt.Dimension;
  15. import java.awt.Rectangle;
  16. import java.io.IOException;
  17. import java.io.ObjectInputStream;
  18. import java.io.ObjectOutputStream;
  19. import java.io.Serializable;
  20. import java.util.Enumeration;
  21. import java.util.Vector;
  22.  
  23. public abstract class AbstractTreeUI extends TreeUI implements Serializable, TreeModelListener, RowMapper, TreeSelectionListener {
  24.    protected transient TreeModel treeModel;
  25.    protected boolean rootVisible;
  26.    protected VisibleTreeNode treeCacheRoot;
  27.    protected Vector visibleNodes = new Vector();
  28.    protected boolean updateNodeSizes;
  29.    protected int rowHeight = 16;
  30.    protected boolean showsRootHandles;
  31.    protected TreeSelectionModel treeSelectionModel;
  32.    protected LargeTreeModelNode largeRoot;
  33.    protected boolean largeModel;
  34.    protected int largeRowCount;
  35.  
  36.    public void collapsePath(TreePath path) {
  37.       if (!this.largeModel) {
  38.          VisibleTreeNode[] nodePath = this.getNodesForTreePath(path, false, true);
  39.          if (nodePath != null) {
  40.             int counter = 0;
  41.  
  42.             for(int maxCounter = nodePath.length - 1; counter < maxCounter; ++counter) {
  43.                if (!nodePath[counter].isExpanded()) {
  44.                   nodePath[counter].expand();
  45.                }
  46.             }
  47.  
  48.             if (nodePath.length > 0) {
  49.                nodePath[counter].collapse();
  50.             }
  51.          }
  52.       } else if (path != null) {
  53.          LargeTreeModelNode node = this.getLargeTreeModelNodeForPath(path.getPath(), false, true);
  54.          if (node != null) {
  55.             node.collapse(true);
  56.          }
  57.       }
  58.  
  59.    }
  60.  
  61.    public void collapseRow(int row) {
  62.       if (row >= 0 && row < this.getRowCount()) {
  63.          if (!this.largeModel) {
  64.             this.getNode(row).collapse();
  65.          } else {
  66.             LargeTreeModelNode node = this.getLargeTreeModelNodeForRow(row, false);
  67.             if (node != null) {
  68.                node.collapse(true);
  69.             }
  70.          }
  71.       }
  72.  
  73.    }
  74.  
  75.    protected LargeTreeModelNode createLargeTreeModelNodeForValue(Object value, int childIndex) {
  76.       return new LargeTreeModelNode(this, value, childIndex);
  77.    }
  78.  
  79.    protected VisibleTreeNode createNodeAt(VisibleTreeNode parent, int childIndex) {
  80.       VisibleTreeNode newChildNode;
  81.       try {
  82.          Object newValue = this.treeModel.getChild(parent.getValue(), childIndex);
  83.          newChildNode = this.createNodeForValue(newValue, -1);
  84.          ((DefaultMutableTreeNode)parent).insert(newChildNode, childIndex);
  85.       } catch (Exception var8) {
  86.          newChildNode = null;
  87.       }
  88.  
  89.       boolean isParentRoot = parent == this.treeCacheRoot;
  90.       if (newChildNode != null && parent.isExpanded() && (parent.getRow() != -1 || isParentRoot)) {
  91.          int newRow;
  92.          if (childIndex == 0) {
  93.             if (isParentRoot && !this.isRootVisible()) {
  94.                newRow = 0;
  95.             } else {
  96.                newRow = parent.getRow() + 1;
  97.             }
  98.          } else if (childIndex == ((DefaultMutableTreeNode)parent).getChildCount()) {
  99.             newRow = parent.getLastVisibleNode().getRow() + 1;
  100.          } else {
  101.             VisibleTreeNode previousNode = (VisibleTreeNode)((DefaultMutableTreeNode)parent).getChildAt(childIndex - 1);
  102.             newRow = previousNode.getLastVisibleNode().getRow() + 1;
  103.          }
  104.  
  105.          this.visibleNodes.insertElementAt(newChildNode, newRow);
  106.       }
  107.  
  108.       return newChildNode;
  109.    }
  110.  
  111.    protected VisibleTreeNode createNodeForValue(Object value, int index) {
  112.       return new VisibleTreeNode(this, value, index);
  113.    }
  114.  
  115.    protected AbstractTreePath createTreePathFor(VisibleTreeNode node) {
  116.       return new AbstractTreePath(((DefaultMutableTreeNode)node).getUserObjectPath(), node);
  117.    }
  118.  
  119.    protected boolean ensureLargePathIsExpanded(TreePath path, boolean expandLast) {
  120.       Object[] aPath = path.getPath();
  121.       if (aPath != null) {
  122.          int pathLength = aPath.length;
  123.          if (this.treeModel.isLeaf(aPath[pathLength - 1])) {
  124.             if (pathLength == 1) {
  125.                aPath = null;
  126.             } else {
  127.                Object[] tPath = new Object[pathLength - 1];
  128.                System.arraycopy(aPath, 0, tPath, 0, pathLength - 1);
  129.                aPath = tPath;
  130.                expandLast = true;
  131.             }
  132.          }
  133.  
  134.          if (aPath != null) {
  135.             LargeTreeModelNode lastNode = this.getLargeTreeModelNodeForPath(aPath, false, true);
  136.             if (lastNode != null) {
  137.                Object[] expPath = ((DefaultMutableTreeNode)lastNode).getPath();
  138.                int maxCounter = expPath.length - 1;
  139.  
  140.                for(int counter = 0; counter < maxCounter; ++counter) {
  141.                   ((LargeTreeModelNode)expPath[counter]).expand(true);
  142.                }
  143.  
  144.                if (expandLast) {
  145.                   ((LargeTreeModelNode)expPath[maxCounter]).expand(true);
  146.                }
  147.  
  148.                return true;
  149.             }
  150.          }
  151.       }
  152.  
  153.       return false;
  154.    }
  155.  
  156.    protected TreePath ensurePathIsAbstract(TreePath path, VisibleTreeNode node) {
  157.       return (TreePath)(path != null && !(path instanceof AbstractTreePath) ? new AbstractTreePath(path.getPath(), node) : path);
  158.    }
  159.  
  160.    protected VisibleTreeNode[] ensurePathIsExpanded(TreePath path, boolean expandLast) {
  161.       VisibleTreeNode[] nodePath = this.getNodesForTreePath(path, false, true);
  162.       if (nodePath != null) {
  163.          int counter = 0;
  164.  
  165.          for(int maxCounter = expandLast ? nodePath.length : nodePath.length - 1; counter < maxCounter; ++counter) {
  166.             if (!nodePath[counter].isExpanded()) {
  167.                nodePath[counter].expand();
  168.             }
  169.          }
  170.       }
  171.  
  172.       return nodePath;
  173.    }
  174.  
  175.    public void expandPath(TreePath path) {
  176.       if (path != null) {
  177.          if (!this.largeModel) {
  178.             this.ensurePathIsExpanded(path, true);
  179.          } else {
  180.             this.ensureLargePathIsExpanded(path, true);
  181.          }
  182.       }
  183.  
  184.    }
  185.  
  186.    public void expandRow(int row) {
  187.       if (row >= 0 && row < this.getRowCount()) {
  188.          if (!this.largeModel) {
  189.             this.getNode(row).expand();
  190.          } else {
  191.             LargeTreeModelNode node = this.getLargeTreeModelNodeForRow(row, true);
  192.             if (node != null) {
  193.                node.expand(true);
  194.             }
  195.          }
  196.       }
  197.  
  198.    }
  199.  
  200.    public TreePath getClosestPathForLocation(int x, int y) {
  201.       if (this.getRowCount() == 0) {
  202.          return null;
  203.       } else {
  204.          int row = this.getRowContainingYLocation(y);
  205.          return !this.largeModel ? this.getNode(row).getTreePath() : this.getLargePathForRow(row);
  206.       }
  207.    }
  208.  
  209.    public int getClosestRowForLocation(int x, int y) {
  210.       return this.getRowCount() == 0 ? -1 : this.getRowContainingYLocation(y);
  211.    }
  212.  
  213.    protected abstract Rectangle getLargeBoundsOf(LargeTreeModelNode var1, int var2, Object var3);
  214.  
  215.    protected LargeTreeModelNode getLargeParentAndChildIndexOfRow(int row, int[] cIndex) {
  216.       int[] rowIndex = new int[1];
  217.       LargeTreeModelNode[] retNode = new LargeTreeModelNode[1];
  218.       boolean[] isParent = new boolean[1];
  219.       if (this.isRootVisible()) {
  220.          rowIndex[0] = 0;
  221.       } else {
  222.          rowIndex[0] = -1;
  223.       }
  224.  
  225.       if (this.largeRoot.getPathForRow(row, rowIndex, (TreePath[])null, retNode, isParent, cIndex)) {
  226.          if (isParent[0]) {
  227.             return retNode[0];
  228.          } else {
  229.             cIndex[0] = retNode[0].getChildIndex();
  230.             return (LargeTreeModelNode)retNode[0].getParent();
  231.          }
  232.       } else {
  233.          return null;
  234.       }
  235.    }
  236.  
  237.    protected TreePath getLargePathForRow(int row) {
  238.       int[] rowIndex = new int[1];
  239.       TreePath[] retPath = new TreePath[1];
  240.       if (this.isRootVisible()) {
  241.          rowIndex[0] = 0;
  242.       } else {
  243.          rowIndex[0] = -1;
  244.       }
  245.  
  246.       return this.largeRoot.getPathForRow(row, rowIndex, retPath, (LargeTreeModelNode[])null, (boolean[])null, (int[])null) ? retPath[0] : null;
  247.    }
  248.  
  249.    protected int getLargeRowForPath(Object[] path) {
  250.       int[] rowIndex = new int[1];
  251.       if (this.isRootVisible()) {
  252.          rowIndex[0] = 0;
  253.       } else {
  254.          rowIndex[0] = -1;
  255.       }
  256.  
  257.       return path != null && this.largeRoot.getRow(path, 0, path.length, true, rowIndex) ? rowIndex[0] : -1;
  258.    }
  259.  
  260.    protected LargeTreeModelNode getLargeTreeModelNodeForPath(Object[] path, boolean onlyIfVisible, boolean shouldCreate) {
  261.       if (path != null) {
  262.          int pathLength = path.length;
  263.          if (pathLength > 0) {
  264.             return this.getLargeTreeModelNodeForPath(path, onlyIfVisible, shouldCreate, pathLength);
  265.          }
  266.       }
  267.  
  268.       return null;
  269.    }
  270.  
  271.    protected LargeTreeModelNode getLargeTreeModelNodeForPath(Object[] path, boolean onlyIfVisible, boolean shouldCreate, int pathLength) {
  272.       if (!path[0].equals(this.largeRoot.getUserObject())) {
  273.          return null;
  274.       } else {
  275.          LargeTreeModelNode lastParent = this.largeRoot;
  276.  
  277.          for(int counter = 1; counter < pathLength; ++counter) {
  278.             if (onlyIfVisible && !lastParent.isExpanded) {
  279.                return null;
  280.             }
  281.  
  282.             int wantIndex = this.treeModel.getIndexOfChild(((DefaultMutableTreeNode)lastParent).getUserObject(), path[counter]);
  283.             if (wantIndex < 0) {
  284.                throw new RuntimeException("invalid index " + wantIndex + " for path " + path[counter]);
  285.             }
  286.  
  287.             int maxCCounter = ((DefaultMutableTreeNode)lastParent).getChildCount();
  288.             LargeTreeModelNode beginLastParent = lastParent;
  289.  
  290.             for(int cCounter = 0; cCounter < maxCCounter; ++cCounter) {
  291.                LargeTreeModelNode aNode = (LargeTreeModelNode)((DefaultMutableTreeNode)lastParent).getChildAt(cCounter);
  292.                if (aNode.childIndex == wantIndex) {
  293.                   lastParent = aNode;
  294.                   cCounter = maxCCounter;
  295.                } else if (aNode.childIndex > wantIndex) {
  296.                   if (!shouldCreate) {
  297.                      return null;
  298.                   }
  299.  
  300.                   LargeTreeModelNode newNode = this.createLargeTreeModelNodeForValue(path[counter], wantIndex);
  301.                   ((DefaultMutableTreeNode)lastParent).insert(newNode, cCounter);
  302.                   lastParent = newNode;
  303.                   cCounter = maxCCounter;
  304.                }
  305.             }
  306.  
  307.             if (beginLastParent == lastParent) {
  308.                if (!shouldCreate) {
  309.                   return null;
  310.                }
  311.  
  312.                LargeTreeModelNode newNode = this.createLargeTreeModelNodeForValue(path[counter], wantIndex);
  313.                ((DefaultMutableTreeNode)lastParent).add(newNode);
  314.                lastParent = newNode;
  315.             }
  316.          }
  317.  
  318.          return lastParent;
  319.       }
  320.    }
  321.  
  322.    protected LargeTreeModelNode getLargeTreeModelNodeForRow(int row, boolean shouldCreate) {
  323.       int[] rowIndex = new int[1];
  324.       int[] cIndex = new int[1];
  325.       LargeTreeModelNode[] retNode = new LargeTreeModelNode[1];
  326.       boolean[] isParent = new boolean[1];
  327.       if (this.isRootVisible()) {
  328.          rowIndex[0] = 0;
  329.       } else {
  330.          rowIndex[0] = -1;
  331.       }
  332.  
  333.       if (this.largeRoot.getPathForRow(row, rowIndex, (TreePath[])null, retNode, isParent, cIndex)) {
  334.          if (isParent[0]) {
  335.             if (shouldCreate) {
  336.                Object childUO = this.treeModel.getChild(retNode[0].getUserObject(), cIndex[0]);
  337.                if (this.treeModel.isLeaf(childUO)) {
  338.                   return null;
  339.                } else {
  340.                   LargeTreeModelNode newNode = this.createLargeTreeModelNodeForValue(childUO, cIndex[0]);
  341.                   retNode[0].addLargeTreeModelNode(newNode);
  342.                   return newNode;
  343.                }
  344.             } else {
  345.                return null;
  346.             }
  347.          } else {
  348.             return retNode[0];
  349.          }
  350.       } else {
  351.          return null;
  352.       }
  353.    }
  354.  
  355.    public int getMaxNodeWidth() {
  356.       int maxWidth = 0;
  357.       if (!this.largeModel) {
  358.          for(int counter = this.getRowCount() - 1; counter >= 0; --counter) {
  359.             VisibleTreeNode node = this.getNode(counter);
  360.             int nodeMaxX;
  361.             if ((nodeMaxX = node.getPreferredSize().width + this.getXOriginOfNode(node)) > maxWidth) {
  362.                maxWidth = nodeMaxX;
  363.             }
  364.          }
  365.       } else {
  366.          for(int counter = this.getRowCount() - 1; counter >= 0; --counter) {
  367.             Rectangle var5 = this.getRowBounds(counter);
  368.             maxWidth = Math.max(maxWidth, var5.x + var5.width);
  369.          }
  370.       }
  371.  
  372.       return maxWidth;
  373.    }
  374.  
  375.    public int getMaxSelectionRow() {
  376.       return this.treeSelectionModel != null ? this.treeSelectionModel.getMaxSelectionRow() : -1;
  377.    }
  378.  
  379.    public int getMinSelectionRow() {
  380.       return this.treeSelectionModel != null ? this.treeSelectionModel.getMinSelectionRow() : -1;
  381.    }
  382.  
  383.    public TreeModel getModel() {
  384.       return this.treeModel;
  385.    }
  386.  
  387.    public VisibleTreeNode getNode(int row) {
  388.       return (VisibleTreeNode)this.visibleNodes.elementAt(row);
  389.    }
  390.  
  391.    public VisibleTreeNode getNodeForPath(Object[] path, boolean onlyIfVisible, boolean shouldCreate) {
  392.       VisibleTreeNode[] nodes = this.getNodesForPath(path, onlyIfVisible, shouldCreate);
  393.       return nodes != null && nodes.length > 0 ? nodes[nodes.length - 1] : null;
  394.    }
  395.  
  396.    protected VisibleTreeNode getNodeForTreePath(TreePath path, boolean onlyIfVisible, boolean shouldCreate) {
  397.       if (this.isAbstractTreePath(path, onlyIfVisible, shouldCreate)) {
  398.          VisibleTreeNode vtn = ((AbstractTreePath)path).node;
  399.          if (vtn == null) {
  400.             return null;
  401.          } else {
  402.             return onlyIfVisible && !vtn.isVisible() ? null : vtn;
  403.          }
  404.       } else {
  405.          return path != null ? this.getNodeForPath(path.getPath(), onlyIfVisible, shouldCreate) : null;
  406.       }
  407.    }
  408.  
  409.    public VisibleTreeNode[] getNodesForPath(Object[] path, boolean onlyIfVisible, boolean shouldCreate) {
  410.       if (path != null && path.length > 0 && this.treeModel != null) {
  411.          if (!this.treeCacheRoot.getValue().equals(path[0])) {
  412.             return null;
  413.          } else {
  414.             VisibleTreeNode retNode = this.treeCacheRoot;
  415.             int counter = 1;
  416.             if (onlyIfVisible && path.length > 1 && !retNode.isExpanded()) {
  417.                return null;
  418.             } else {
  419.                VisibleTreeNode[] nodePath = new VisibleTreeNode[path.length];
  420.                nodePath[0] = retNode;
  421.  
  422.                while(retNode != null && counter < path.length) {
  423.                   VisibleTreeNode newNode = null;
  424.                   Enumeration childEnum = retNode.getLoadedChildren(shouldCreate);
  425.  
  426.                   while(childEnum.hasMoreElements() && newNode == null) {
  427.                      newNode = (VisibleTreeNode)childEnum.nextElement();
  428.                      if (!newNode.getValue().equals(path[counter])) {
  429.                         newNode = null;
  430.                      }
  431.                   }
  432.  
  433.                   retNode = newNode;
  434.                   nodePath[counter] = newNode;
  435.                   ++counter;
  436.                   if (newNode != null && onlyIfVisible && counter < path.length && !newNode.isExpanded()) {
  437.                      retNode = null;
  438.                   }
  439.                }
  440.  
  441.                return retNode != null ? nodePath : null;
  442.             }
  443.          }
  444.       } else {
  445.          return null;
  446.       }
  447.    }
  448.  
  449.    protected VisibleTreeNode[] getNodesForTreePath(TreePath path, boolean onlyIfVisible, boolean shouldCreate) {
  450.       if (this.isAbstractTreePath(path, onlyIfVisible, shouldCreate)) {
  451.          VisibleTreeNode vtn = ((AbstractTreePath)path).node;
  452.          if (vtn == null) {
  453.             return null;
  454.          } else if (onlyIfVisible && !vtn.isVisible()) {
  455.             return null;
  456.          } else {
  457.             TreeNode[] tPath = ((DefaultMutableTreeNode)vtn).getPath();
  458.             VisibleTreeNode[] cPath = new VisibleTreeNode[tPath.length];
  459.             System.arraycopy(tPath, 0, cPath, 0, tPath.length);
  460.             return cPath;
  461.          }
  462.       } else {
  463.          return path != null ? this.getNodesForPath(path.getPath(), onlyIfVisible, shouldCreate) : null;
  464.       }
  465.    }
  466.  
  467.    public Rectangle getPathBounds(TreePath path) {
  468.       if (!this.largeModel) {
  469.          VisibleTreeNode node = this.getNodeForTreePath(path, true, false);
  470.          if (node != null) {
  471.             return node.getNodeBounds();
  472.          }
  473.       } else if (path != null) {
  474.          return this.getRowBounds(this.getRowForPath(path));
  475.       }
  476.  
  477.       return null;
  478.    }
  479.  
  480.    public TreePath getPathForRow(int row) {
  481.       if (row >= 0 && row < this.getRowCount()) {
  482.          return !this.largeModel ? this.getNode(row).getTreePath() : this.getLargePathForRow(row);
  483.       } else {
  484.          return null;
  485.       }
  486.    }
  487.  
  488.    public TreePath[] getPathsForRows(int[] rows) {
  489.       if (rows == null) {
  490.          return null;
  491.       } else {
  492.          int numRows = rows.length;
  493.          TreePath[] paths = new TreePath[numRows];
  494.  
  495.          for(int counter = 0; counter < numRows; ++counter) {
  496.             paths[counter] = this.getPathForRow(rows[counter]);
  497.          }
  498.  
  499.          return paths;
  500.       }
  501.    }
  502.  
  503.    public Rectangle getRowBounds(int row) {
  504.       if (row >= 0 && row < this.getRowCount()) {
  505.          if (!this.largeModel) {
  506.             return this.getNode(row).getNodeBounds();
  507.          }
  508.  
  509.          if (row == 0 && this.isRootVisible()) {
  510.             return this.getLargeBoundsOf((LargeTreeModelNode)null, 0, this.largeRoot.getUserObject());
  511.          }
  512.  
  513.          int[] cIndex = new int[1];
  514.          LargeTreeModelNode parent = this.getLargeParentAndChildIndexOfRow(row, cIndex);
  515.          if (parent != null) {
  516.             return this.getLargeBoundsOf(parent, row, this.treeModel.getChild(((DefaultMutableTreeNode)parent).getUserObject(), cIndex[0]));
  517.          }
  518.       }
  519.  
  520.       return null;
  521.    }
  522.  
  523.    public int getRowContainingYLocation(int location) {
  524.       if (this.isFixedRowHeight()) {
  525.          return this.getRowCount() == 0 ? -1 : Math.max(0, Math.min(this.getRowCount() - 1, location / this.getRowHeight()));
  526.       } else {
  527.          int max;
  528.          if ((max = this.getRowCount()) <= 0) {
  529.             return -1;
  530.          } else {
  531.             int min = 0;
  532.             int mid = 0;
  533.  
  534.             while(min < max) {
  535.                mid = (max - min) / 2 + min;
  536.                VisibleTreeNode node = (VisibleTreeNode)this.visibleNodes.elementAt(mid);
  537.                int minY = node.getYOrigin();
  538.                int maxY = minY + node.getPreferredSize().height;
  539.                if (location < minY) {
  540.                   max = mid - 1;
  541.                } else {
  542.                   if (location < maxY) {
  543.                      break;
  544.                   }
  545.  
  546.                   min = mid + 1;
  547.                }
  548.             }
  549.  
  550.             if (min == max) {
  551.                mid = min;
  552.                if (min >= this.getRowCount()) {
  553.                   mid = this.getRowCount() - 1;
  554.                }
  555.             }
  556.  
  557.             return mid;
  558.          }
  559.       }
  560.    }
  561.  
  562.    public int getRowCount() {
  563.       return !this.largeModel ? this.visibleNodes.size() : this.largeRowCount;
  564.    }
  565.  
  566.    public int getRowForPath(TreePath path) {
  567.       if (path == null) {
  568.          return -1;
  569.       } else if (!this.largeModel) {
  570.          VisibleTreeNode visNode = this.getNodeForTreePath(path, true, false);
  571.          return visNode != null ? visNode.getRow() : -1;
  572.       } else {
  573.          return this.getLargeRowForPath(path.getPath());
  574.       }
  575.    }
  576.  
  577.    public int getRowHeight() {
  578.       return this.rowHeight;
  579.    }
  580.  
  581.    public int[] getRowsForPaths(TreePath[] paths) {
  582.       if (paths == null) {
  583.          return null;
  584.       } else {
  585.          int numPaths = paths.length;
  586.          int[] rows = new int[numPaths];
  587.  
  588.          for(int counter = 0; counter < numPaths; ++counter) {
  589.             rows[counter] = this.getRowForPath(paths[counter]);
  590.          }
  591.  
  592.          return rows;
  593.       }
  594.    }
  595.  
  596.    public TreeSelectionModel getSelectionModel() {
  597.       return this.treeSelectionModel;
  598.    }
  599.  
  600.    public TreePath getSelectionPath() {
  601.       return this.treeSelectionModel != null ? this.treeSelectionModel.getSelectionPath() : null;
  602.    }
  603.  
  604.    public TreePath[] getSelectionPaths() {
  605.       return this.treeSelectionModel != null ? this.treeSelectionModel.getSelectionPaths() : null;
  606.    }
  607.  
  608.    public int[] getSelectionRows() {
  609.       return this.treeSelectionModel != null ? this.treeSelectionModel.getSelectionRows() : null;
  610.    }
  611.  
  612.    public boolean getShowsRootHandles() {
  613.       return this.showsRootHandles;
  614.    }
  615.  
  616.    public abstract Dimension getSizeOfNode(VisibleTreeNode var1, int var2);
  617.  
  618.    public Object getValue(int row) {
  619.       if (!this.largeModel) {
  620.          return this.getNode(row).getValue();
  621.       } else {
  622.          int[] cIndex = new int[1];
  623.          LargeTreeModelNode eNode = this.getLargeParentAndChildIndexOfRow(row, cIndex);
  624.          if (row == 0 && this.isRootVisible()) {
  625.             return this.treeModel.getRoot();
  626.          } else {
  627.             return eNode != null ? this.treeModel.getChild(((DefaultMutableTreeNode)eNode).getUserObject(), cIndex[0]) : null;
  628.          }
  629.       }
  630.    }
  631.  
  632.    public abstract int getXOriginOfNode(VisibleTreeNode var1);
  633.  
  634.    public int getYOriginOfRow(int row) {
  635.       if (row < 0) {
  636.          return -1;
  637.       } else if (row >= this.getRowCount()) {
  638.          return -1;
  639.       } else {
  640.          return this.isFixedRowHeight() ? row * this.getRowHeight() : this.getNode(row).getYOrigin();
  641.       }
  642.    }
  643.  
  644.    protected boolean isAbstractTreePath(TreePath path, boolean onlyIfVisible, boolean shouldCreate) {
  645.       if (path != null && path instanceof AbstractTreePath) {
  646.          AbstractTreePath atPath = (AbstractTreePath)path;
  647.          if (atPath.node == null || atPath.getUI() == this) {
  648.             if (atPath.node == null || !atPath.node.isValid) {
  649.                atPath.node = this.getNodeForPath(path.getPath(), false, shouldCreate);
  650.                if (atPath.node == null) {
  651.                   return false;
  652.                }
  653.             }
  654.  
  655.             return true;
  656.          }
  657.       }
  658.  
  659.       return false;
  660.    }
  661.  
  662.    public boolean isCollapsed(int row) {
  663.       return !this.isExpanded(row);
  664.    }
  665.  
  666.    public boolean isCollapsed(TreePath path) {
  667.       return !this.isExpanded(path);
  668.    }
  669.  
  670.    public boolean isExpanded(int row) {
  671.       if (!this.largeModel) {
  672.          return this.getNode(row).isExpanded();
  673.       } else {
  674.          LargeTreeModelNode eNode = this.getLargeTreeModelNodeForRow(row, false);
  675.          return eNode != null ? eNode.isExpanded() : false;
  676.       }
  677.    }
  678.  
  679.    public boolean isExpanded(TreePath path) {
  680.       if (!this.largeModel) {
  681.          VisibleTreeNode lastNode = this.getNodeForTreePath(path, true, false);
  682.          if (lastNode != null) {
  683.             return lastNode.isExpanded();
  684.          }
  685.       } else if (path != null) {
  686.          LargeTreeModelNode lastNode = this.getLargeTreeModelNodeForPath(path.getPath(), true, false);
  687.          if (lastNode != null && lastNode.isExpanded()) {
  688.             return true;
  689.          }
  690.  
  691.          return false;
  692.       }
  693.  
  694.       return false;
  695.    }
  696.  
  697.    public boolean isFixedRowHeight() {
  698.       return this.rowHeight > 0;
  699.    }
  700.  
  701.    public boolean isLargeModel() {
  702.       return this.largeModel;
  703.    }
  704.  
  705.    public boolean isLeaf(int row) {
  706.       if (!this.largeModel) {
  707.          VisibleTreeNode node = this.getNode(row);
  708.          if (node != null) {
  709.             return node.isLeaf();
  710.          }
  711.       } else {
  712.          if (row == 0 && this.isRootVisible()) {
  713.             return this.treeModel.isLeaf(this.treeModel.getRoot());
  714.          }
  715.  
  716.          int[] childIndex = new int[1];
  717.          LargeTreeModelNode parent = this.getLargeParentAndChildIndexOfRow(row, childIndex);
  718.          if (parent != null) {
  719.             return this.treeModel.isLeaf(this.treeModel.getChild(((DefaultMutableTreeNode)parent).getUserObject(), childIndex[0]));
  720.          }
  721.       }
  722.  
  723.       return true;
  724.    }
  725.  
  726.    public boolean isPathSelected(TreePath path) {
  727.       return this.treeSelectionModel != null ? this.treeSelectionModel.isPathSelected(path) : false;
  728.    }
  729.  
  730.    public boolean isRootVisible() {
  731.       return this.rootVisible;
  732.    }
  733.  
  734.    public boolean isRowSelected(int row) {
  735.       return this.treeSelectionModel != null ? this.treeSelectionModel.isRowSelected(row) : false;
  736.    }
  737.  
  738.    public boolean isSelectedIndex(int row) {
  739.       return this.treeSelectionModel != null ? this.treeSelectionModel.isRowSelected(row) : false;
  740.    }
  741.  
  742.    public boolean isVisible(TreePath path) {
  743.       if (!this.largeModel) {
  744.          VisibleTreeNode lastNode = this.getNodeForTreePath(path, true, false);
  745.          if (lastNode != null) {
  746.             return true;
  747.          }
  748.       } else if (path != null) {
  749.          Object[] oPath = path.getPath();
  750.          if (oPath != null) {
  751.             int pathLength = oPath.length;
  752.             if (pathLength > 0) {
  753.                if (this.treeModel.isLeaf(oPath[pathLength - 1]) && pathLength > 1) {
  754.                   Object[] tempPath = new Object[pathLength - 1];
  755.                   System.arraycopy(oPath, 0, tempPath, 0, pathLength - 1);
  756.                   LargeTreeModelNode var7 = this.getLargeTreeModelNodeForPath(tempPath, true, false);
  757.                   if (var7 != null && var7.isVisible() && var7.isExpanded()) {
  758.                      return true;
  759.                   }
  760.  
  761.                   return false;
  762.                }
  763.  
  764.                LargeTreeModelNode lastNode = this.getLargeTreeModelNodeForPath(oPath, true, false);
  765.                return lastNode.isVisible();
  766.             }
  767.          }
  768.       }
  769.  
  770.       return false;
  771.    }
  772.  
  773.    public void makeVisible(TreePath path) {
  774.       if (!this.largeModel) {
  775.          this.ensurePathIsExpanded(path, false);
  776.       } else {
  777.          this.ensureLargePathIsExpanded(path, false);
  778.       }
  779.  
  780.    }
  781.  
  782.    protected abstract void pathWasCollapsed(TreePath var1);
  783.  
  784.    protected abstract void pathWasExpanded(TreePath var1);
  785.  
  786.    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
  787.       s.defaultReadObject();
  788.       Vector values = (Vector)s.readObject();
  789.       int indexCounter = 0;
  790.       int maxCounter = values.size();
  791.       if (indexCounter < maxCounter && values.elementAt(indexCounter).equals("treeModel")) {
  792.          ++indexCounter;
  793.          this.treeModel = (TreeModel)values.elementAt(indexCounter);
  794.          ++indexCounter;
  795.       }
  796.  
  797.       if (indexCounter < maxCounter && values.elementAt(indexCounter).equals("treeSelectionModel")) {
  798.          ++indexCounter;
  799.          this.treeSelectionModel = (TreeSelectionModel)values.elementAt(indexCounter);
  800.          ++indexCounter;
  801.       }
  802.  
  803.    }
  804.  
  805.    public void rebuild() {
  806.       if (!this.largeModel && this.treeCacheRoot != null) {
  807.          this.treeCacheRoot.markInvalid();
  808.       }
  809.  
  810.       if (this.treeModel != null) {
  811.          if (!this.largeModel) {
  812.             this.largeRoot = null;
  813.             this.treeCacheRoot = this.createNodeForValue(this.treeModel.getRoot(), 0);
  814.             this.visibleNodes.removeAllElements();
  815.             if (this.isRootVisible()) {
  816.                this.visibleNodes.addElement(this.treeCacheRoot);
  817.             }
  818.  
  819.             if (!this.treeCacheRoot.isExpanded()) {
  820.                this.treeCacheRoot.expand();
  821.             } else {
  822.                Enumeration cursor = this.treeCacheRoot.children();
  823.  
  824.                while(cursor.hasMoreElements()) {
  825.                   this.visibleNodes.addElement(cursor.nextElement());
  826.                }
  827.  
  828.                if (!this.isFixedRowHeight()) {
  829.                   this.updateYLocationsFrom(0);
  830.                }
  831.             }
  832.          } else {
  833.             this.treeCacheRoot = null;
  834.             this.visibleNodes.removeAllElements();
  835.             this.largeRoot = this.createLargeTreeModelNodeForValue(this.treeModel.getRoot(), 0);
  836.             if (this.isRootVisible()) {
  837.                this.largeRowCount = 1;
  838.             } else {
  839.                this.largeRowCount = 0;
  840.             }
  841.  
  842.             this.largeRoot.expand(true);
  843.          }
  844.       } else {
  845.          this.visibleNodes.removeAllElements();
  846.          this.treeCacheRoot = null;
  847.          this.largeRoot = null;
  848.          this.largeRowCount = 0;
  849.       }
  850.  
  851.       if (this.treeSelectionModel != null) {
  852.          this.treeSelectionModel.clearSelection();
  853.       }
  854.  
  855.       this.visibleNodesChanged();
  856.    }
  857.  
  858.    public void setLargeModel(boolean largeModel) {
  859.       if (this.largeModel != largeModel) {
  860.          this.largeModel = largeModel;
  861.          if (largeModel && this.rowHeight <= 0) {
  862.             this.rowHeight = 16;
  863.          }
  864.  
  865.          this.rebuild();
  866.       }
  867.  
  868.    }
  869.  
  870.    public void setModel(TreeModel newModel) {
  871.       TreeModel oldModel = this.treeModel;
  872.       if (newModel != oldModel) {
  873.          if (oldModel != null) {
  874.             oldModel.removeTreeModelListener(this);
  875.          }
  876.  
  877.          this.treeModel = newModel;
  878.          if (this.treeModel != null) {
  879.             this.treeModel.addTreeModelListener(this);
  880.          }
  881.  
  882.          this.rebuild();
  883.       }
  884.  
  885.    }
  886.  
  887.    public void setRootVisible(boolean rootVisible) {
  888.       if (rootVisible != this.rootVisible) {
  889.          this.rootVisible = rootVisible;
  890.          if (this.treeModel != null) {
  891.             if (!this.largeModel) {
  892.                if (this.rootVisible) {
  893.                   this.treeCacheRoot.updatePreferredSize(0);
  894.                   this.visibleNodes.insertElementAt(this.treeCacheRoot, 0);
  895.                } else if (this.visibleNodes.size() > 0) {
  896.                   this.visibleNodes.removeElementAt(0);
  897.                   if (this.treeSelectionModel != null) {
  898.                      this.treeSelectionModel.removeSelectionPath(this.treeCacheRoot.getTreePath());
  899.                   }
  900.                }
  901.  
  902.                if (this.treeSelectionModel != null) {
  903.                   this.treeSelectionModel.resetRowSelection();
  904.                }
  905.  
  906.                if (this.getRowCount() > 0) {
  907.                   this.getNode(0).setYOrigin(0);
  908.                }
  909.  
  910.                this.updateYLocationsFrom(0);
  911.                this.visibleNodesChanged();
  912.             } else {
  913.                if (this.rootVisible) {
  914.                   ++this.largeRowCount;
  915.                } else {
  916.                   --this.largeRowCount;
  917.                }
  918.  
  919.                if (this.treeSelectionModel != null) {
  920.                   this.treeSelectionModel.clearSelection();
  921.                }
  922.  
  923.                this.visibleNodesChanged();
  924.             }
  925.          }
  926.       }
  927.  
  928.    }
  929.  
  930.    public void setRowHeight(int rowHeight) {
  931.       if (rowHeight != this.rowHeight) {
  932.          if (!this.largeModel) {
  933.             this.rowHeight = rowHeight;
  934.             if (!this.isFixedRowHeight() && this.visibleNodes.size() > 0) {
  935.                this.updateNodeSizes(true);
  936.             } else if (this.isFixedRowHeight()) {
  937.                for(int counter = this.getRowCount() - 1; counter >= 0; --counter) {
  938.                   this.getNode(counter).getPreferredSize().height = rowHeight;
  939.                }
  940.             }
  941.  
  942.             this.visibleNodesChanged();
  943.          } else {
  944.             if (rowHeight <= 0) {
  945.                throw new IllegalArgumentException("AbstractTreeUI.setRowHeight() row height must be > 0 for large models");
  946.             }
  947.  
  948.             this.rowHeight = rowHeight;
  949.             this.visibleNodesChanged();
  950.          }
  951.       }
  952.  
  953.    }
  954.  
  955.    public void setSelectionModel(TreeSelectionModel newLSM) {
  956.       if (this.treeSelectionModel != newLSM) {
  957.          if (this.treeSelectionModel != null) {
  958.             this.treeSelectionModel.removeTreeSelectionListener(this);
  959.             this.treeSelectionModel.setRowMapper((RowMapper)null);
  960.          }
  961.  
  962.          this.treeSelectionModel = newLSM;
  963.          if (this.treeSelectionModel != null) {
  964.             this.treeSelectionModel.addTreeSelectionListener(this);
  965.             this.treeSelectionModel.setRowMapper(this);
  966.             this.treeSelectionModel.resetRowSelection();
  967.          }
  968.       }
  969.  
  970.    }
  971.  
  972.    public void setShowsRootHandles(boolean newValue) {
  973.       if (this.showsRootHandles != newValue) {
  974.          this.showsRootHandles = newValue;
  975.          this.visibleNodesChanged();
  976.       }
  977.  
  978.    }
  979.  
  980.    public synchronized void treeNodesChanged(TreeModelEvent e) {
  981.       if (e != null) {
  982.          if (this.largeModel) {
  983.             this.visibleNodesChanged();
  984.          } else {
  985.             int[] changedIndexs = e.getChildIndices();
  986.             VisibleTreeNode changedNode = this.getNodeForPath(e.getPath(), false, false);
  987.             if (changedNode != null) {
  988.                Object changedValue = changedNode.getValue();
  989.                changedNode.updatePreferredSize();
  990.                if (changedIndexs != null) {
  991.                   for(int counter = 0; counter < changedIndexs.length; ++counter) {
  992.                      try {
  993.                         VisibleTreeNode changedChildNode = (VisibleTreeNode)((DefaultMutableTreeNode)changedNode).getChildAt(changedIndexs[counter]);
  994.                         ((DefaultMutableTreeNode)changedChildNode).setUserObject(this.treeModel.getChild(changedValue, changedIndexs[counter]));
  995.                         changedChildNode.updatePreferredSize();
  996.                      } catch (Exception var7) {
  997.                      }
  998.                   }
  999.                }
  1000.  
  1001.                if (!this.isFixedRowHeight()) {
  1002.                   int aRow = changedNode.getRow();
  1003.                   if (aRow != -1) {
  1004.                      this.updateYLocationsFrom(aRow);
  1005.                   }
  1006.                }
  1007.  
  1008.                this.visibleNodesChanged();
  1009.             }
  1010.          }
  1011.       }
  1012.  
  1013.    }
  1014.  
  1015.    public synchronized void treeNodesInserted(TreeModelEvent e) {
  1016.       if (e != null && !this.largeModel) {
  1017.          int[] changedIndexs = e.getChildIndices();
  1018.          VisibleTreeNode changedParent = this.getNodeForPath(e.getPath(), false, false);
  1019.          if (changedParent != null && changedIndexs != null && changedIndexs.length > 0) {
  1020.             if (changedParent.hasBeenExpanded()) {
  1021.                changedParent.getValue();
  1022.                boolean maxCounter = changedParent == this.treeCacheRoot && !this.rootVisible || changedParent.getRow() != -1 && changedParent.isExpanded();
  1023.  
  1024.                for(int isVisible = 0; isVisible < changedIndexs.length; ++isVisible) {
  1025.                   this.createNodeAt(changedParent, changedIndexs[isVisible]);
  1026.                }
  1027.  
  1028.                if (this.treeSelectionModel != null) {
  1029.                   this.treeSelectionModel.resetRowSelection();
  1030.                }
  1031.  
  1032.                if (!this.isFixedRowHeight() && maxCounter) {
  1033.                   if (changedParent == this.treeCacheRoot) {
  1034.                      this.updateYLocationsFrom(0);
  1035.                   } else {
  1036.                      this.updateYLocationsFrom(changedParent.getRow());
  1037.                   }
  1038.  
  1039.                   this.visibleNodesChanged();
  1040.                } else if (maxCounter) {
  1041.                   this.visibleNodesChanged();
  1042.                }
  1043.             } else {
  1044.                changedParent.modelChildCountChanged();
  1045.             }
  1046.          }
  1047.       } else if (e != null) {
  1048.          LargeTreeModelNode changedParent = this.getLargeTreeModelNodeForPath(e.getPath(), false, false);
  1049.          int[] changedIndexs = e.getChildIndices();
  1050.          int makeVisible;
  1051.          if (changedParent != null && changedIndexs != null && (makeVisible = changedIndexs.length) > 0) {
  1052.             boolean isVisible = changedParent.isVisible() && changedParent.isExpanded();
  1053.  
  1054.             for(int counter = 0; counter < makeVisible; ++counter) {
  1055.                changedParent.childInsertedAtModelIndex(changedIndexs[counter]);
  1056.                if (isVisible) {
  1057.                   ++this.largeRowCount;
  1058.                }
  1059.             }
  1060.  
  1061.             if (isVisible && this.treeSelectionModel != null) {
  1062.                this.treeSelectionModel.resetRowSelection();
  1063.             }
  1064.  
  1065.             if (isVisible) {
  1066.                this.visibleNodesChanged();
  1067.             } else {
  1068.                changedParent.modelChildCountChanged();
  1069.             }
  1070.          }
  1071.       }
  1072.  
  1073.    }
  1074.  
  1075.    public synchronized void treeNodesRemoved(TreeModelEvent e) {
  1076.       if (e != null && !this.largeModel) {
  1077.          int[] changedIndexs = e.getChildIndices();
  1078.          VisibleTreeNode maxCounter = this.getNodeForPath(e.getPath(), false, false);
  1079.          if (maxCounter != null && changedIndexs != null && changedIndexs.length > 0) {
  1080.             if (maxCounter.hasBeenExpanded()) {
  1081.                boolean parentPath = maxCounter == this.treeCacheRoot && !this.rootVisible || maxCounter.getRow() != -1 && maxCounter.isExpanded();
  1082.  
  1083.                for(int changedParentNode = changedIndexs.length - 1; changedParentNode >= 0; --changedParentNode) {
  1084.                   try {
  1085.                      VisibleTreeNode children = (VisibleTreeNode)((DefaultMutableTreeNode)maxCounter).getChildAt(changedIndexs[changedParentNode]);
  1086.                      if (children.isExpanded()) {
  1087.                         children.collapse(false);
  1088.                      }
  1089.  
  1090.                      if (parentPath) {
  1091.                         int childPath = children.getRow();
  1092.                         if (childPath != -1) {
  1093.                            this.visibleNodes.removeElementAt(childPath);
  1094.                            if (this.treeSelectionModel != null) {
  1095.                               TreePath oldPath = children.getTreePath();
  1096.                               this.treeSelectionModel.removeSelectionPath(oldPath);
  1097.                            }
  1098.                         }
  1099.                      }
  1100.  
  1101.                      ((DefaultMutableTreeNode)maxCounter).remove(children);
  1102.                   } catch (Exception var12) {
  1103.                      System.out.println("Exception removing node" + var12);
  1104.                   }
  1105.                }
  1106.  
  1107.                if (this.treeSelectionModel != null) {
  1108.                   this.treeSelectionModel.resetRowSelection();
  1109.                }
  1110.  
  1111.                if (!this.isFixedRowHeight() && parentPath) {
  1112.                   if (maxCounter == this.treeCacheRoot) {
  1113.                      if (this.getRowCount() > 0) {
  1114.                         this.getNode(0).setYOrigin(0);
  1115.                      }
  1116.  
  1117.                      this.updateYLocationsFrom(0);
  1118.                   } else {
  1119.                      this.updateYLocationsFrom(maxCounter.getRow());
  1120.                   }
  1121.  
  1122.                   this.visibleNodesChanged();
  1123.                } else if (parentPath) {
  1124.                   this.visibleNodesChanged();
  1125.                }
  1126.             } else {
  1127.                maxCounter.modelChildCountChanged();
  1128.             }
  1129.          }
  1130.       } else if (e != null) {
  1131.          Object[] parentPath = e.getPath();
  1132.          LargeTreeModelNode changedParentNode = this.getLargeTreeModelNodeForPath(parentPath, false, false);
  1133.          int[] changedIndexs = e.getChildIndices();
  1134.          int changedParentNode;
  1135.          if (changedParentNode != null && changedIndexs != null && (changedParentNode = changedIndexs.length) > 0) {
  1136.             Object[] children = e.getChildren();
  1137.             int parentPathLength = parentPath.length;
  1138.             boolean isVisible = changedParentNode.isVisible() && changedParentNode.isExpanded();
  1139.  
  1140.             for(int counter = 0; counter < changedParentNode; ++counter) {
  1141.                LargeTreeModelNode childNode = changedParentNode.childAtModelIndex(changedIndexs[counter]);
  1142.                if (childNode != null) {
  1143.                   childNode.collapse(false);
  1144.                   ((DefaultMutableTreeNode)changedParentNode).remove(childNode);
  1145.                }
  1146.  
  1147.                if (isVisible) {
  1148.                   --this.largeRowCount;
  1149.                }
  1150.  
  1151.                changedParentNode.childRemovedAtModelIndex(changedIndexs[counter]);
  1152.                if (this.treeSelectionModel != null && children != null && children[counter] != null) {
  1153.                   Object[] removedRow = new Object[parentPathLength + 1];
  1154.                   System.arraycopy(parentPath, 0, removedRow, 0, parentPathLength);
  1155.                   removedRow[parentPathLength] = children[counter];
  1156.                   this.treeSelectionModel.removeSelectionPath(new TreePath(removedRow));
  1157.                }
  1158.             }
  1159.  
  1160.             if (isVisible) {
  1161.                if (this.treeSelectionModel != null) {
  1162.                   this.treeSelectionModel.resetRowSelection();
  1163.                }
  1164.  
  1165.                this.visibleNodesChanged();
  1166.             } else {
  1167.                changedParentNode.modelChildCountChanged();
  1168.             }
  1169.          }
  1170.       }
  1171.  
  1172.    }
  1173.  
  1174.    public synchronized void treeStructureChanged(TreeModelEvent e) {
  1175.       if (e != null && !this.largeModel) {
  1176.          Object[] changedPath = e.getPath();
  1177.          VisibleTreeNode var12 = this.getNodeForPath(changedPath, false, false);
  1178.          if (var12 == null && changedPath != null && changedPath.length == 1) {
  1179.             var12 = this.treeCacheRoot;
  1180.          }
  1181.  
  1182.          if (var12 != null) {
  1183.             boolean wasExpanded = var12.isExpanded();
  1184.             boolean wasVisible = var12.getRow() != -1;
  1185.             if (var12 == this.treeCacheRoot) {
  1186.                this.rebuild();
  1187.             } else {
  1188.                VisibleTreeNode parent = (VisibleTreeNode)((DefaultMutableTreeNode)var12).getParent();
  1189.                int nodeIndex = ((DefaultMutableTreeNode)parent).getIndex(var12);
  1190.                if (wasVisible && wasExpanded) {
  1191.                   var12.collapse(false);
  1192.                }
  1193.  
  1194.                if (wasVisible) {
  1195.                   this.visibleNodes.removeElement(var12);
  1196.                }
  1197.  
  1198.                ((DefaultMutableTreeNode)var12).removeFromParent();
  1199.                this.createNodeAt(parent, nodeIndex);
  1200.                VisibleTreeNode newNode = (VisibleTreeNode)((DefaultMutableTreeNode)parent).getChildAt(nodeIndex);
  1201.                if (wasVisible && wasExpanded) {
  1202.                   newNode.expand(false);
  1203.                }
  1204.  
  1205.                int parent = newNode.getRow();
  1206.                if (!this.isFixedRowHeight() && wasVisible) {
  1207.                   if (parent == 0) {
  1208.                      this.updateYLocationsFrom(parent);
  1209.                   } else {
  1210.                      this.updateYLocationsFrom(parent - 1);
  1211.                   }
  1212.  
  1213.                   this.visibleNodesChanged();
  1214.                } else if (wasVisible) {
  1215.                   this.visibleNodesChanged();
  1216.                }
  1217.             }
  1218.          }
  1219.       } else if (e != null) {
  1220.          Object[] changedPath = e.getPath();
  1221.          if (changedPath != null && changedPath.length > 0) {
  1222.             if (changedPath.length == 1) {
  1223.                this.rebuild();
  1224.             } else {
  1225.                LargeTreeModelNode changedNode = this.getLargeTreeModelNodeForPath(changedPath, false, false);
  1226.                if (changedNode != null) {
  1227.                   LargeTreeModelNode parent = (LargeTreeModelNode)((DefaultMutableTreeNode)changedNode).getParent();
  1228.                   boolean wasExpanded = changedNode.isExpanded();
  1229.                   boolean wasVisible = changedNode.isVisible();
  1230.                   if (wasVisible && wasExpanded) {
  1231.                      changedNode.collapse(false);
  1232.                      ((DefaultMutableTreeNode)changedNode).removeFromParent();
  1233.                      changedNode = this.getLargeTreeModelNodeForPath(changedPath, false, true);
  1234.                      changedNode.expand(false);
  1235.                   } else {
  1236.                      ((DefaultMutableTreeNode)changedNode).removeFromParent();
  1237.                   }
  1238.  
  1239.                   if (this.treeSelectionModel != null && wasVisible && wasExpanded) {
  1240.                      this.treeSelectionModel.resetRowSelection();
  1241.                   }
  1242.  
  1243.                   if (wasVisible) {
  1244.                      this.visibleNodesChanged();
  1245.                   } else {
  1246.                      parent.modelChildCountChanged();
  1247.                   }
  1248.                }
  1249.             }
  1250.          }
  1251.       }
  1252.  
  1253.    }
  1254.  
  1255.    public void updateNodeSizes(boolean updateAll) {
  1256.       this.updateNodeSizes = false;
  1257.       int counter = 0;
  1258.       int aY = 0;
  1259.  
  1260.       for(int maxCounter = this.visibleNodes.size(); counter < maxCounter; ++counter) {
  1261.          VisibleTreeNode node = (VisibleTreeNode)this.visibleNodes.elementAt(counter);
  1262.          node.setYOrigin(aY);
  1263.          if (updateAll || !node.hasValidSize()) {
  1264.             node.updatePreferredSize(counter);
  1265.          }
  1266.  
  1267.          aY += node.getPreferredSize().height;
  1268.       }
  1269.  
  1270.    }
  1271.  
  1272.    protected void updateYLocationsFrom(int location) {
  1273.       if (location >= 0 && location < this.getRowCount()) {
  1274.          VisibleTreeNode aNode = this.getNode(location);
  1275.          int newYOrigin = aNode.getYOrigin() + aNode.getPreferredSize().height;
  1276.          int counter = location + 1;
  1277.  
  1278.          for(int maxCounter = this.visibleNodes.size(); counter < maxCounter; ++counter) {
  1279.             aNode = (VisibleTreeNode)this.visibleNodes.elementAt(counter);
  1280.             aNode.setYOrigin(newYOrigin);
  1281.             newYOrigin += aNode.getPreferredSize().height;
  1282.          }
  1283.       }
  1284.  
  1285.    }
  1286.  
  1287.    public void valueChanged(TreeSelectionEvent e) {
  1288.       if (this.treeSelectionModel != null) {
  1289.          TreePath[] paths = this.treeSelectionModel.getSelectionPaths();
  1290.          if (paths != null) {
  1291.             for(int counter = paths.length - 1; counter >= 0; --counter) {
  1292.                this.makeVisible(paths[counter]);
  1293.             }
  1294.          }
  1295.       }
  1296.  
  1297.    }
  1298.  
  1299.    public Enumeration visibleNodes() {
  1300.       return this.visibleNodes.elements();
  1301.    }
  1302.  
  1303.    public abstract void visibleNodesChanged();
  1304.  
  1305.    private void writeObject(ObjectOutputStream s) throws IOException {
  1306.       Vector values = new Vector();
  1307.       s.defaultWriteObject();
  1308.       if (this.treeModel != null && this.treeModel instanceof Serializable) {
  1309.          values.addElement("treeModel");
  1310.          values.addElement(this.treeModel);
  1311.       }
  1312.  
  1313.       if (this.treeSelectionModel != null && this.treeSelectionModel instanceof Serializable) {
  1314.          values.addElement("treeSelectionModel");
  1315.          values.addElement(this.treeSelectionModel);
  1316.       }
  1317.  
  1318.       s.writeObject(values);
  1319.    }
  1320. }
  1321.